
即使没有模板，C++头文件也会变得非常大，因此需要很长时间来编译。模板增加了这种趋势，由于开发者的强烈抗议，驱使供应商了一种称为预编译头文件(PCH)的方案。该方案在标准范围之外运行，并依赖于特定于供应商的选项。尽管如何创建和使用预编译头文件的信息，在具有此特性的各种C++编译系统的文档中有介绍，但对其工作原理多少还要了解一下。

当编译器翻译一个文件时，其会从文件的开头开始，一直翻译到末尾。当处理来自文件(可能来自\#include的文件)的标记时，会调整它的内部状态，包括像向符号表添加条目这样的事情，以便后续查找。这样做的同时，编译器也可以在目标文件中生成代码。

预编译头方案依赖于:许多文件以相同的代码行开始。为了方便讨论，假设每个要编译的文件都以相同的N行代码开始。可以编译这N行，并将编译器的完整状态保存在一个预编译头中。然后，对于程序中的每个文件，可以重新加载保存的状态，并在第N+1行开始编译，重新加载保存的状态的操作比实际编译前N行要快几个数量级。然而，首先保存状态的开销通常比编译N行代码更大，成本的增加大约在20\%到200\%之间。

有效使用预编译头的关键是确保(尽可能多的)文件以最大数量的公共代码行开始。实践中，文件必须以相同的\#include指令开始，这些指令(如前所述)消耗了构建时间的很大一部分。因此，头文件的包含顺序也很重要。例如以下两个文件:

\begin{lstlisting}[style=styleCXX]
#include <iostream>
#include <vector>
#include <list>
...
\end{lstlisting}

和

\begin{lstlisting}[style=styleCXX]
#include <list>
#include <vector>
...
\end{lstlisting}

禁止使用预编译头文件，因为源文件中没有常见的初始状态。

一些开发者决定，与其传递使用预编译头来加速文件的翻译，不如包含一些额外的不必要的头文件。这个决定可以大大简化包含政策的管理。例如，创建一个名为std.hpp的头文件通常是相对简单的，包含所有标准头文件:

\begin{tcolorbox}[colback=webgreen!5!white,colframe=webgreen!75!black]
\hspace*{0.75cm}理论上，标准头文件实际上不需要与物理文件相对应。在实践中，确实如此，而且文件非常大。
\end{tcolorbox}

\begin{lstlisting}[style=styleCXX]
#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <list>
...
\end{lstlisting}

可以对这个文件进行预编译，然后每个使用标准库的程序文件就可以按如下方式启动:

\begin{lstlisting}[style=styleCXX]
#include "std.hpp"
...
\end{lstlisting}

通常，这将需要一段时间来编译。但若系统有足够的内存，预编译头文件的处理速度快于不进行预编译的标准头文件。标准头文件在这种方式下特别方便，因为它们很少更改，因此std.hpp文件的预编译头文件只需要构建一次。否则，预编译头文件通常是项目依赖配置的一部分(例如，会根据需要由构建工具或集成开发环境(IDE)的项目构建工具进行更新)。

管理预编译头文件的方法是创建预编译头文件层，这些头文件层从最广泛使用和最稳定的头文件(例如，std.hpp头文件)到那些不会随时更改的头文件，因此仍然可以使用预编译的头文件。但若头文件需要大量开发，那创建预编译的头文件所花费的时间，可能比重用它们要要多。这种方法的关键概念是，可以重用较稳定层的预编译头，以提高较不稳定头文件的预编译时间。例如，假设除了std.hpp头文件(已经预编译过了)，还要定义了一个core.hpp头文件，包含了一些特定于项目的附加工具，但仍然具有一定程度的稳定性:

\begin{lstlisting}[style=styleCXX]
#include "std.hpp"
#include "core_data.hpp"
#include "core_algos.hpp"
...
\end{lstlisting}

因为该文件以\#include "standard.hpp"开始，编译器可以加载相关的预编译头文件，并继续下一行，而无需重新编译所有标准头文件。当文件完全处理后，可以生成一个新的预编译头文件。因为编译器可以加载后一个预编译头文件，多以应用可以使用\#include "core.hpp"来快速提供对大量功能的访问。























